#!/usr/bin/env python3
"""
用户管理API
提供用户相关的CRUD操作和认证功能
"""

from typing import List, Optional
from datetime import datetime, timedelta
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload
from sqlmodel import select, and_, or_
from jose import JWTError, jwt
import bcrypt
from pydantic import Field

from database.connection import get_session
from database.models import User, UserRole, Order
from validators.user_validator import (
    UserCreate, UserUpdate, UserResponse, UserLogin, 
    Token, UserPasswordChange
)
from utils.file_upload import get_file_manager


router = APIRouter(prefix="/api/users", tags=["用户管理"])

# JWT配置
SECRET_KEY = "your-secret-key-here"  # 应该从环境变量获取
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="api/users/login")


def verify_password(plain_password: str, hashed_password: str) -> bool:
    """验证密码"""
    return bcrypt.checkpw(plain_password.encode('utf-8'), hashed_password.encode('utf-8'))


def get_password_hash(password: str) -> str:
    """生成密码哈希"""
    return bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')


def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
    """创建访问令牌"""
    to_encode = data.copy()
    if expires_delta:
        expire = datetime.utcnow() + expires_delta
    else:
        expire = datetime.utcnow() + timedelta(minutes=15)
    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
    return encoded_jwt


async def get_current_user(token: str = Depends(oauth2_scheme), session: AsyncSession = Depends(get_session)):
    """获取当前用户"""
    credentials_exception = HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="无法验证凭据",
        headers={"WWW-Authenticate": "Bearer"},
    )
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        username: str = payload.get("sub")
        if username is None:
            raise credentials_exception
    except JWTError:
        raise credentials_exception
    
    result = await session.execute(select(User).where(User.username == username))
    user = result.scalar_one_or_none()
    
    if user is None:
        raise credentials_exception
    return user


async def get_current_active_user(current_user: User = Depends(get_current_user)):
    """获取当前活跃用户"""
    if not current_user.is_active:
        raise HTTPException(status_code=400, detail="用户未激活")
    return current_user


@router.post("/register", response_model=UserResponse)
async def register_user(
    user_data: UserCreate,
    session: AsyncSession = Depends(get_session)
):
    """用户注册"""
    # 检查用户名是否已存在
    result = await session.execute(select(User).where(User.username == user_data.username))
    existing_user = result.scalar_one_or_none()
    
    if existing_user:
        raise HTTPException(status_code=400, detail="用户名已存在")
    
    # 检查邮箱是否已存在
    result = await session.execute(select(User).where(User.email == user_data.email))
    existing_user = result.scalar_one_or_none()
    
    if existing_user:
        raise HTTPException(status_code=400, detail="邮箱已存在")
    
    # 创建用户
    hashed_password = get_password_hash(user_data.password)
    
    user = User(
        email=user_data.email,
        username=user_data.username,
        hashed_password=hashed_password,
        full_name=user_data.full_name,
        phone=user_data.phone,
        role=user_data.role,
        is_active=True
    )
    
    session.add(user)
    await session.commit()
    await session.refresh(user)
    
    return user


@router.post("/login", response_model=Token)
async def login_user(
    form_data: OAuth2PasswordRequestForm = Depends(),
    session: AsyncSession = Depends(get_session)
):
    """用户登录"""
    # Debug logging
    print(f"DEBUG: Login attempt - username: {form_data.username}, password: {form_data.password}, grant_type: {form_data.grant_type}")
    
    # 查找用户
    result = await session.execute(select(User).where(User.username == form_data.username))
    user = result.scalar_one_or_none()
    
    print(f"DEBUG: User found: {user is not None}")
    if user:
        print(f"DEBUG: User details - ID: {user.id}, username: {user.username}, is_active: {user.is_active}")
        print(f"DEBUG: Password verification: {verify_password(form_data.password, user.hashed_password)}")
    
    if not user or not verify_password(form_data.password, user.hashed_password):
        print(f"DEBUG: Login failed - user exists: {user is not None}, password valid: {verify_password(form_data.password, user.hashed_password) if user else 'N/A'}")
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="用户名或密码错误",
            headers={"WWW-Authenticate": "Bearer"},
        )
    
    if not user.is_active:
        raise HTTPException(status_code=400, detail="用户未激活")
    
    # 创建访问令牌
    access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    access_token = create_access_token(
        data={"sub": user.username}, expires_delta=access_token_expires
    )
    
    # 更新最后登录时间（如果用户模型有last_login字段）
    if hasattr(user, 'last_login'):
        user.last_login = datetime.utcnow()
        session.add(user)
        await session.commit()
    
    print(f"DEBUG: Login successful for user: {user.username}")
    
    return {
        "access_token": access_token,
        "token_type": "bearer",
        "user_id": user.id,
        "username": user.username,
        "role": user.role.value
    }


@router.get("/me", response_model=UserResponse)
async def get_current_user_info(current_user: User = Depends(get_current_active_user)):
    """获取当前用户信息"""
    return current_user


@router.get("/", response_model=List[UserResponse])
async def get_users(
    skip: int = 0,
    limit: int = 100,
    role: Optional[UserRole] = None,
    is_active: Optional[bool] = None,
    search: Optional[str] = None,
    session: AsyncSession = Depends(get_session)
):
    """获取用户列表（管理员功能）"""
    query = select(User)
    
    # 应用筛选条件
    if role:
        query = query.where(User.role == role)
    
    if is_active is not None:
        query = query.where(User.is_active == is_active)
    
    if search:
        query = query.where(
            or_(
                User.username.contains(search),
                User.full_name.contains(search),
                User.email.contains(search)
            )
        )
    
    # 排序和分页
    query = query.order_by(User.created_at.desc())
    query = query.offset(skip).limit(limit)
    
    result = await session.execute(query)
    users = result.scalars().all()
    
    return users


@router.get("/{user_id}", response_model=UserResponse)
async def get_user(
    user_id: int,
    session: AsyncSession = Depends(get_session)
):
    """获取单个用户信息"""
    result = await session.execute(select(User).where(User.id == user_id))
    user = result.scalar_one_or_none()
    
    if not user:
        raise HTTPException(status_code=404, detail="用户不存在")
    
    return user


@router.put("/{user_id}", response_model=UserResponse)
async def update_user(
    user_id: int,
    user_update: UserUpdate,
    current_user: User = Depends(get_current_active_user),
    session: AsyncSession = Depends(get_session)
):
    """更新用户信息"""
    # 检查权限（用户只能更新自己的信息，管理员可以更新所有用户）
    if current_user.role != UserRole.ADMIN and current_user.id != user_id:
        raise HTTPException(status_code=403, detail="权限不足")
    
    result = await session.execute(select(User).where(User.id == user_id))
    user = result.scalar_one_or_none()
    
    if not user:
        raise HTTPException(status_code=404, detail="用户不存在")
    
    # 更新字段
    update_data = user_update.dict(exclude_unset=True)
    
    # 如果更新邮箱，检查邮箱是否已存在
    if 'email' in update_data and update_data['email'] != user.email:
        result = await session.execute(select(User).where(User.email == update_data['email']))
        existing_user = result.scalar_one_or_none()
        if existing_user:
            raise HTTPException(status_code=400, detail="邮箱已存在")
    
    # 如果更新用户名，检查用户名是否已存在
    if 'username' in update_data and update_data['username'] != user.username:
        result = await session.execute(select(User).where(User.username == update_data['username']))
        existing_user = result.scalar_one_or_none()
        if existing_user:
            raise HTTPException(status_code=400, detail="用户名已存在")
    
    for field, value in update_data.items():
        setattr(user, field, value)
    
    user.updated_at = datetime.utcnow()
    
    await session.commit()
    await session.refresh(user)
    
    return user


@router.put("/{user_id}/password")
async def change_password(
    user_id: int,
    password_data: UserPasswordChange,
    current_user: User = Depends(get_current_active_user),
    session: AsyncSession = Depends(get_session)
):
    """修改用户密码"""
    # 检查权限（用户只能修改自己的密码，管理员可以修改所有用户密码）
    if current_user.role != UserRole.ADMIN and current_user.id != user_id:
        raise HTTPException(status_code=403, detail="权限不足")
    
    result = await session.execute(select(User).where(User.id == user_id))
    user = result.scalar_one_or_none()
    
    if not user:
        raise HTTPException(status_code=404, detail="用户不存在")
    
    # 验证旧密码（非管理员用户需要验证）
    if current_user.role != UserRole.ADMIN:
        if not verify_password(password_data.old_password, user.hashed_password):
            raise HTTPException(status_code=400, detail="原密码错误")
    
    # 更新密码
    user.hashed_password = get_password_hash(password_data.new_password)
    user.updated_at = datetime.utcnow()
    
    await session.commit()
    
    return {"message": "密码修改成功"}


@router.put("/{user_id}/activate")
async def activate_user(
    user_id: int,
    is_active: bool,
    current_user: User = Depends(get_current_active_user),
    session: AsyncSession = Depends(get_session)
):
    """激活/禁用用户（管理员功能）"""
    # 检查权限
    if current_user.role != UserRole.ADMIN:
        raise HTTPException(status_code=403, detail="权限不足")
    
    result = await session.execute(select(User).where(User.id == user_id))
    user = result.scalar_one_or_none()
    
    if not user:
        raise HTTPException(status_code=404, detail="用户不存在")
    
    user.is_active = is_active
    user.updated_at = datetime.utcnow()
    
    await session.commit()
    
    status_text = "激活" if is_active else "禁用"
    return {"message": f"用户{status_text}成功"}


@router.delete("/{user_id}")
async def delete_user(
    user_id: int,
    current_user: User = Depends(get_current_active_user),
    session: AsyncSession = Depends(get_session)
):
    """删除用户（管理员功能）"""
    # 检查权限
    if current_user.role != UserRole.ADMIN:
        raise HTTPException(status_code=403, detail="权限不足")
    
    result = await session.execute(select(User).where(User.id == user_id))
    user = result.scalar_one_or_none()
    
    if not user:
        raise HTTPException(status_code=404, detail="用户不存在")
    
    # 检查是否有相关订单
    result = await session.execute(select(Order).where(Order.user_id == user_id).limit(1))
    existing_order = result.scalar_one_or_none()
    
    if existing_order:
        raise HTTPException(status_code=400, detail="该用户存在订单记录，不能删除")
    
    await session.delete(user)
    await session.commit()
    
    return {"message": "用户删除成功"}


@router.get("/{user_id}/orders")
async def get_user_orders(
    user_id: int,
    skip: int = 0,
    limit: int = 100,
    status: Optional[str] = None,
    session: AsyncSession = Depends(get_session)
):
    """获取用户订单列表"""
    # 检查权限
    current_user = await get_current_active_user()
    if current_user.role != UserRole.ADMIN and current_user.id != user_id:
        raise HTTPException(status_code=403, detail="权限不足")
    
    query = select(Order).options(selectinload(Order.product)).where(Order.user_id == user_id)
    
    if status:
        query = query.where(Order.status == status)
    
    query = query.order_by(Order.created_at.desc())
    query = query.offset(skip).limit(limit)
    
    result = await session.execute(query)
    orders = result.scalars().all()
    
    return orders


@router.get("/stats/summary")
async def get_user_stats(
    start_date: Optional[datetime] = None,
    end_date: Optional[datetime] = None,
    current_user: User = Depends(get_current_active_user),
    session: AsyncSession = Depends(get_session)
):
    """获取用户统计信息（管理员功能）"""
    if current_user.role != UserRole.ADMIN:
        raise HTTPException(status_code=403, detail="权限不足")
    
    query = select(User)
    
    if start_date:
        query = query.where(User.created_at >= start_date)
    
    if end_date:
        query = query.where(User.created_at <= end_date)
    
    result = await session.execute(query)
    users = result.scalars().all()
    
    # 统计信息
    total_users = len(users)
    active_users = len([u for u in users if u.is_active])
    
    role_counts = {}
    for user in users:
        role = user.role.value
        role_counts[role] = role_counts.get(role, 0) + 1
    
    return {
        "total_users": total_users,
        "active_users": active_users,
        "inactive_users": total_users - active_users,
        "role_counts": role_counts,
        "activation_rate": (active_users / total_users * 100) if total_users > 0 else 0
    }